~ chicken-core (master) /manual/Module (chicken process)


  1[[tags: manual]]
  2[[toc:]]
  3
  4== Module (chicken process)
  5
  6This module offers procedures for interacting with subprocesses.
  7
  8Note:
  9Errors caused by underlying C calls that
 10change errno will produce a condition object with an {{errno}}
 11property, which can be accessed with
 12{{(get-condition-property <the-condition-object> 'exn 'errno)}}.
 13
 14=== Processes
 15
 16==== process-execute
 17
 18<procedure>(process-execute PATHNAME [ARGUMENT-LIST [ENVIRONMENT-ALIST]])</procedure>
 19
 20Replaces the running process with a new process image from the program
 21stored at {{PATHNAME}}, using the C library function {{execvp(3)}}.
 22If the optional argument {{ARGUMENT-LIST}} is given, then it should
 23contain a list of strings which are passed as arguments to the subprocess.
 24If the optional argument {{ENVIRONMENT-ALIST}} is supplied, then the library
 25function {{execve(2)}} is used, and the environment passed in
 26{{ENVIRONMENT-ALIST}} (which should be of the form {{(("<NAME>" . "<VALUE>") ...)}})
 27is given to the invoked process. Note that {{execvp(3)}} respects the
 28current setting of the {{PATH}} environment variable while {{execve(3)}} does not.
 29
 30This procedure never returns; it either replaces the process with a new one
 31or it raises an exception in case something went wrong executing the program.
 32
 33On Windows, these procedures all have an additional optional parameter
 34{{EXACT-FLAG}}, which defaults to {{#f}}. When {{#f}} is passed, any
 35argument string with embedded whitespace will be wrapped in
 36quotes. When {{#t}} no such wrapping occurs.
 37
 38
 39==== process-fork
 40
 41<procedure>(process-fork [THUNK [KILLOTHERS?]])</procedure>
 42
 43Creates a new child process with the UNIX system call
 44{{fork()}}. In the parent process this procedure returns a process-object representing the child process
 45and in the child process {{process-fork}} returns {{#f}}.
 46If {{THUNK}} is given, then the child process calls it as a procedure
 47with no arguments and terminates. If {{THUNK}} is given and the
 48optional argument {{KILLOTHERS?}} is true, then kill all other
 49existing threads in the child process, leaving only the current thread
 50to run {{THUNK}} and terminate.
 51
 52'''NOTE''': On native Windows builds (all except cygwin), this
 53procedure is unimplemented and will raise an error.
 54
 55==== process-run
 56
 57<procedure>(process-run COMMANDLINE)</procedure><br>
 58<procedure>(process-run COMMAND ARGUMENT-LIST)</procedure>
 59
 60Creates a new child process. The process object representing the new process is returned.
 61
 62* The single parameter version passes the {{COMMANDLINE}} to the
 63system shell, so usual argument expansion can take place.  Be careful
 64to properly quote arguments with the {{qs}} procedure to avoid shell
 65injection vulnerabilities.
 66* The multiple parameter version directly invokes the {{COMMAND}} with
 67the {{ARGUMENT-LIST}}, and is vastly preferred over the
 68single-parameter version because of its better safety.
 69
 70==== process-signal
 71
 72<procedure>(process-signal PROCESS [SIGNAL])</procedure>
 73
 74Sends {{SIGNAL}} to the process with the integer id or prcoess
 75object {{PROCESS}} using the
 76UNIX system call {{kill()}}. {{SIGNAL}} defaults to the value
 77of the variable {{signal/term}}.
 78
 79'''NOTE''': On native Windows builds (all except cygwin), this
 80procedure is unimplemented and will raise an error.
 81
 82==== process-spawn
 83
 84<procedure>(process-spawn MODE COMMAND [ARGUMENT-LIST [ENVIRONMENT-LIST [EXACT-FLAG]]])</procedure>
 85
 86Creates and runs a new process with the given {{COMMAND}} filename and
 87the optional {{ARGUMENT-LIST}} and {{ENVIRONMENT-LIST}}. {{MODE}}
 88specifies how exactly the process should be executed and must be one
 89or more of the {{spawn/...}} flags listed below.
 90
 91The {{EXACT-FLAG}}, default {{#f}}, controls quote-wrapping of
 92argument strings. When {{#t}} quote-wrapping is not performed.
 93
 94Returns:
 95* the exit status when synchronous
 96* a process object when asynchronous
 97
 98'''NOTE''': On all Unix-like builds (all except native MingW-based
 99Windows platforms), this procedure is unimplemented and will raise an
100error.
101
102<constant>spawn/overlay</constant>
103<constant>spawn/wait</constant>
104<constant>spawn/nowait</constant>
105<constant>spawn/nowaito</constant>
106<constant>spawn/detach</constant>
107
108These variables contains special flags that specify the exact
109semantics of {{process-spawn}}:
110
111* {{spawn/overlay}} replaces the current process with the new one.
112* {{spawn/wait}} suspends execution of the current process until the spawned process returns.
113* {{spawn/nowait}} does the opposite ({{spawn/nowaito}} is identical, according to the Microsoft documentation) and runs the process asynchronously.
114* {{spawn/detach}} runs the new process in the background, without being attached to a console.
115
116
117==== process-wait
118
119<procedure>(process-wait [PROCESS [NOHANG]])</procedure>
120
121Suspends the current process until the child process identifier by {{PROCESS}},
122which should be a process object or an integer process id (pid),
123has terminated using the UNIX system call
124{{waitpid()}}. If {{PROCESS}} is not given, then this procedure
125waits for any child process. If {{NOHANG}} is given and not
126{{#f}} then the current process is not suspended.  This procedure
127returns three values:
128
129* {{PID}} or 0, if {{NOHANG}} is true and the child process has not terminated yet.
130* {{#t}} if the process exited normally or {{#f}} otherwise.
131* either the exit status, if the process terminated normally or the signal number that terminated/stopped the process.
132
133Note that suspending the current process implies that all threads
134are suspended as well.
135
136The exit status and the flag indicating whether the process returned normally
137are also stored in {{PROCESS}}, when given to be retrieved later, if desired.
138
139On Windows, {{process-wait}} always returns {{#t}} for a terminated
140process and only the exit status is available. (Windows does not
141provide signals as an interprocess communication method.)
142
143
144==== process-sleep
145
146<procedure>(process-sleep SECONDS)</procedure>
147
148Puts the process to sleep for {{SECONDS}}. Returns either 0 if
149the time has completely elapsed, or the number of remaining seconds,
150if a signal occurred.
151
152
153==== process
154
155<procedure>(process COMMANDLINE)</procedure><br>
156<procedure>(process COMMAND ARGUMENT-LIST [ENVIRONMENT-ALIST ENCODING])</procedure>
157
158Creates a subprocess and returns a process object, with the input- and output
159ports stored in the object, which can be accessed using accessors described
160below.
161
162* The single parameter version passes the string {{COMMANDLINE}} to the host-system's shell that
163is invoked as a subprocess.
164* The multiple parameter version directly invokes the {{COMMAND}} as a subprocess. The {{ARGUMENT-LIST}}
165is directly passed, as is {{ENVIRONMENT-ALIST}}. These arguments have the same form as the ones of {{process-execute}}.
166
167{{ENCODING}} should be a symbol specifying the encoding to be
168used for I/O operations, the default is {{utf-8}}. The encodings for
169the returned in and output ports can be subsequently changed by
170using the {{port-encoding}} setter.
171
172Not using the shell may be preferrable for security reasons.
173
174Once both the input- and output ports are closed, an implicit
175{{waitpid(3)}} is done to wait for the subprocess to finish or to reap
176a subprocess that has terminated. If the subprocess has not finished,
177waiting for it will necessarily block all executing threads. The exit status
178and whether the process exitted normally will be stored in the returned
179process object to be retrieved later by the accessors described below,
180if so desired.
181
182==== process*
183
184<procedure>(process* COMMANDLINE)</procedure><br>
185<procedure>(process* COMMAND ARGUMENT-LIST [ENVIRONMENT-ALIST ENCODING])</procedure>
186
187Like {{process}} but connects also to the error-output port ({{stderr}}) of
188the subprocess.
189
190==== process?
191==== process-id
192==== process-exit-status
193==== process-returned-normally?
194==== process-input-port
195==== process-output-port
196==== process-error-port
197
198<procedure>(process? X)</procedure>
199
200Returns a boolean indicating whether {{X}} is a process object.
201
202<procedure>(process-id PROCESS)</procedure>
203<procedure>(process-exit-status PROCESS)</procedure>
204<procedure>(process-returned-normally? PROCESS)</procedure>
205<procedure>(process-input-port PROCESS)</procedure>
206<procedure>(process-output-port PROCESS)</procedure>
207<procedure>(process-error-port PROCESS)</procedure>
208
209Accessors for process-object attributes. The ports values are only
210defined for processes created with {{process}} or {{process*}} and represent
211the input port from
212which data written by the sub-process can be read, the output port from
213which any data written to will be received as input in the sub-process
214and the error port where to which the sub-process directs its error output.
215Blocking reads and writes
216to or from the ports returned by {{process}} only block the current
217thread, not other threads executing concurrently.
218
219Standard error for the subprocess is linked up to the current
220process's standard error (see {{process*}} if you want to reify
221its standard error into a separate port).
222
223=== Shell commands
224
225The commands below are all string-based.  This means you have to be
226very careful to properly quote any arguments to subprocesses, to avoid
227shell injection bugs which can lead to arbitrary code execution.
228
229You can quote arguments with the {{qs}} procedure, but it is strongly
230recommended you use {{fork}} with {{process-execute}} or the
231multi-argument versions of the {{process}}, {{process*}} or
232{{process-run}} procedures.
233
234==== qs
235
236<procedure>(qs STRING [PLATFORM])</procedure>
237
238Escapes {{STRING}} suitably for passing to a shell command on {{PLATFORM}}.
239{{PLATFORM}} defaults to the value of {{(build-platform)}} and indicates in
240which style the argument should be quoted. On Windows systems, the string
241is simply enclosed in double-quote ({{"}}) characters, on UNIXish systems,
242characters that would have a special meaning to the shell are escaped
243using backslash ({{\}}).
244
245
246==== system
247
248<procedure>(system STRING)</procedure>
249
250Execute shell command. The functionality offered by this procedure
251depends on the capabilities of the host shell. If the forking of a subprocess
252failed, an exception is raised. Otherwise the return status of the
253subprocess is returned unaltered.
254
255
256On a UNIX system, that value is the raw return value of waitpid(2), which contains signal, core dump and exit status.    It is 0 on success.  To pull out the signal number or exit status portably requires POSIX calls, but in a pinch you can use something like this:
257
258<enscript highlight='scheme'>
259;; Returns two values: #t if the process exited normally or #f otherwise;
260;; and either the exit status, or the signal number if terminated via signal.
261(define (process-status rc)
262  (define (wait-signaled? x) (not (= 0 (bitwise-and x 127))))
263  (define (wait-signal x) (bitwise-and x 127))
264  (define (wait-exit-status x) (arithmetic-shift x -8))
265  (if (wait-signaled? rc)
266      (values #f (wait-signal rc))
267      (values #t (wait-exit-status rc))))
268
269#;> (process-status (system "exit 42"))
270#t
27142
272</enscript>
273
274==== system*
275
276<procedure>(system* STRING)</procedure>
277
278Similar to {{(system STRING)}}, but signals an error should the invoked
279program return a nonzero exit status.
280
281=== Pipes
282
283==== call-with-input-pipe
284==== call-with-output-pipe
285
286<procedure>(call-with-input-pipe CMDLINE PROC [MODE])</procedure><br>
287<procedure>(call-with-output-pipe CMDLINE PROC [MODE])</procedure>
288
289Call {{PROC}} with a single argument: a input- or output port
290for a pipe connected to the subprocess named in {{CMDLINE}}. If
291{{PROC}} returns normally, the pipe is closed and any result values
292are returned.
293
294==== close-input-pipe
295==== close-output-pipe
296
297<procedure>(close-input-pipe PORT)</procedure><br>
298<procedure>(close-output-pipe PORT)</procedure>
299
300Closes the pipe given in {{PORT}} and waits until the connected
301subprocess finishes. The exit-status code of the invoked process
302is returned.
303
304==== create-pipe
305
306<procedure>(create-pipe)</procedure>
307
308The fundamental pipe-creation operator. Calls the C function
309{{pipe()}} and returns 2 values: the file-descriptors of the input-
310and output-ends of the pipe.
311
312On Windows, there is an optional parameter {{MODE}}, which defaults
313to {{open/binary | open/noinherit}}. This can be {{open/binary}} or
314{{open/text}}, optionally or'ed with {{open/noinherit}}.
315
316
317==== open-input-pipe
318
319<procedure>(open-input-pipe CMDLINE [MODE])</procedure>
320
321Spawns a subprocess with the command-line string {{CMDLINE}} and
322returns a port, from which the output of the process can be read. If
323{{MODE}} is specified, it should be the keyword {{#:text}}
324(the default) or {{#:binary}}.
325
326==== open-output-pipe
327
328<procedure>(open-output-pipe CMDLINE [MODE])</procedure>
329
330Spawns a subprocess with the command-line string {{CMDLINE}} and
331returns a port. Anything written to that port is treated as the input
332for the process.  If {{MODE}} is specified, it should be the keyword
333{{#:text}} (the default) or {{#:binary}}.
334
335==== pipe/buf
336
337<constant>pipe/buf</constant>
338
339This variable contains the maximal number of bytes that can be written
340atomically into a pipe or FIFO.
341
342==== with-input-from-pipe
343==== with-output-to-pipe
344
345<procedure>(with-input-from-pipe CMDLINE THUNK [MODE])</procedure><br>
346<procedure>(with-output-to-pipe CMDLINE THUNK [MODE])</procedure>
347
348Temporarily set the value of
349{{current-input-port/current-output-port}} to a port for a
350pipe connected to the subprocess named in {{CMDLINE}} and call
351the procedure {{THUNK}} with no arguments. After {{THUNK}}
352returns normally the pipe is closed and the standard input-/output port
353is restored to its previous value and any result values are returned.
354
355<enscript highlight=scheme>
356(with-output-to-pipe
357  "gs -dNOPAUSE -sDEVICE=jpeg -dBATCH -sOutputFile=signballs.jpg -g600x600 -q -"
358  (lambda ()
359    (print #<<EOF
360 %!IOPSC-1993 %%Creator: HAYAKAWA Takashi<xxxxxxxx@xx.xxxxxx.xx.xx>
361 /C/neg/d/mul/R/rlineto/E/exp/H{{cvx def}repeat}def/T/dup/g/gt/r/roll/J/ifelse 8
362 H/A/copy(z&v4QX&93r9AxYQOZomQalxS2w!!O&vMYa43d6r93rMYvx2dca!D&cjSnjSnjjS3o!v&6A
363 X&55SAxM1CD7AjYxTTd62rmxCnTdSST0g&12wECST!&!J0g&D1!&xM0!J0g!l&544dC2Ac96ra!m&3A
364 F&&vGoGSnCT0g&wDmlvGoS8wpn6wpS2wTCpS1Sd7ov7Uk7o4Qkdw!&Mvlx1S7oZES3w!J!J!Q&7185d
365 Z&lx1CS9d9nE4!k&X&MY7!&1!J!x&jdnjdS3odS!N&mmx1C2wEc!G&150Nx4!n&2o!j&43r!U&0777d
366 ]&2AY2A776ddT4oS3oSnMVC00VV0RRR45E42063rNz&v7UX&UOzF!F!J![&44ETCnVn!a&1CDN!Y&0M
367 V1c&j2AYdjmMdjjd!o&1r!M){( )T 0 4 3 r put T(/)g{T(9)g{cvn}{cvi}J}{($)g[]J}J
368 cvx}forall/moveto/p/floor/w/div/S/add 29 H[{[{]setgray fill}for Y}for showpage
369 EOF
370 ) ) )
371</enscript>
372
373=== Windows specific notes
374
375Use of UTF8 encoded strings for pathnames is not supported. Windows
376uses a 16-bit UNICODE encoding with special system calls for
377wide-character support.  Only single-byte string encoding can be used.
378
379---
380Previous: [[Module (chicken pretty-print)]]
381
382Next: [[Module (chicken process signal)]]
Trap